package com.token.iot.bratterycharging.gateway;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.CountDownLatch;

import com.outstanding.framework.core.Logger;
import com.outstanding.framework.core.PendingException;
import com.outstanding.framework.log.LoggerFactory;


public class SemaphoreManager {
	protected static Logger loger = LoggerFactory.getLogger("transactionLogger");
	
	private SemaphoreManager() {
		super();
		// 要设置成后台线程,否则会造成服务器无法正常关闭
		Timer sessionClearTimer = new Timer(true);
		int oneMin = 60000;
		// 1分钟以后开始,每隔一分钟探测一次
		sessionClearTimer.schedule(new SemaphoreCleanerTimerTask(), oneMin, oneMin);
	}
	private static SemaphoreManager instance = new SemaphoreManager();

	
	public static SemaphoreManager getInstance() {
		return instance;
	}

	private static final Map<String, Semaphore> signals = Collections.synchronizedMap(new HashMap());

	// key,值自上次活动以来的时间(分钟)为value
	private static Map signalsActiveMap = Collections.synchronizedMap(new HashMap());

	static public Semaphore registerCommand(String key, Sender sender) {
		Semaphore semaphore = new Semaphore(key, sender);
		CountDownLatch latch = new CountDownLatch(1);
		semaphore.setCountDownLatch(latch);
		signalsActiveMap.put(key, new Integer(0));
		signals.put(key, semaphore);
		return semaphore;
	}

	static public void onResponse(String key, String response) {
		Semaphore semaphore = signals.get(key);
		loger.info("the onResponse key="+key);
		if (semaphore != null) {
			loger.info("the semaphore is not null ="+key);
			semaphore.setResponse(response);
			semaphore.getCountDownLatch().countDown();
		}
		return;
	}

	static public String getResponse(String key) throws PendingException {
		Semaphore semaphore = signals.get(key);
		if (semaphore == null) {
			PendingException pe = new PendingException(ResCode.SeaphoreError);
			pe.setData(key);
			throw pe;
		}
		String response = semaphore.getResponse();
		signalsActiveMap.remove(key);
		signals.remove(key);
		return response;
	}

	/**
	 * 超时的删除
	 * 
	 * @param key
	 * @return
	 * @throws PendingException
	 */
	static public void remove(String key) throws PendingException {
		signals.remove(key);

	}

	protected class SemaphoreCleanerTimerTask extends TimerTask {

		// 从配置文件中得到timeOut时间 分钟。
		private int timeOut = 2;

		public void run() {
			Set idSet = signalsActiveMap.keySet();
			Iterator idIt = idSet.iterator();

			// 已经失效的Semaphore的key列表
			List invalidIdList = new ArrayList();
			while (idIt.hasNext()) {
				String id = (String) idIt.next();

				// 自创建以来的时长
				Integer lastSpan = (Integer) signalsActiveMap.get(id);
				if (lastSpan.intValue() > timeOut) {
					invalidIdList.add(id);
				}
			}
			for (int i = 0, n = invalidIdList.size(); i < n; i++) {
				String id = (String) invalidIdList.get(i);
				Semaphore semaphore = signals.get(id);
				if (semaphore != null) {
					semaphore.getCountDownLatch().countDown();
				}
				signals.remove(id);
				signalsActiveMap.remove(id);
			}
		}

	}
}
